<template>
  <el-dialog
    v-model="visible"
    :title="title"
    :width="width"
    :close-on-click-modal="closeOnClickModal"
    :close-on-press-escape="closeOnPressEscape"
    :show-close="showClose"
    :center="center"
    :destroy-on-close="destroyOnClose"
    @open="handleOpen"
    @opened="handleOpened"
    @close="handleClose"
    @closed="handleClosed"
    @open-auto-focus="handleOpenAutoFocus"
    @close-auto-focus="handleCloseAutoFocus"
  >
    <!-- 表单内容 -->
    <div class="form-dialog-content">
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        :label-width="labelWidth"
        :label-position="labelPosition"
        :size="size"
        :disabled="disabled"
        :validate-on-rule-change="validateOnRuleChange"
      >
        <slot :form-data="formData" :form-ref="formRef"></slot>
      </el-form>
    </div>

    <!-- 底部操作按钮 -->
    <template #footer>
      <div class="form-dialog-footer">
        <slot name="footer" :form-data="formData" :form-ref="formRef">
          <el-button @click="handleCancel" :disabled="loading">
            {{ cancelText }}
          </el-button>
          <el-button
            type="primary"
            @click="handleConfirm"
            :loading="loading"
            :disabled="disabled"
          >
            {{ confirmText }}
          </el-button>
        </slot>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
interface Props {
  // 对话框配置
  modelValue?: boolean;
  title?: string;
  width?: string | number;
  closeOnClickModal?: boolean;
  closeOnPressEscape?: boolean;
  showClose?: boolean;
  center?: boolean;
  destroyOnClose?: boolean;

  // 表单配置
  formData?: Record<string, any>;
  rules?: Record<string, any>;
  labelWidth?: string | number;
  labelPosition?: "left" | "right" | "top";
  size?: "large" | "default" | "small";
  disabled?: boolean;
  validateOnRuleChange?: boolean;

  // 按钮配置
  loading?: boolean;
  confirmText?: string;
  cancelText?: string;

  // 自动重置表单
  autoResetForm?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  title: "表单",
  width: "600px",
  closeOnClickModal: false,
  closeOnPressEscape: true,
  showClose: true,
  center: false,
  destroyOnClose: false,
  formData: () => ({}),
  rules: () => ({}),
  labelWidth: "100px",
  labelPosition: "right",
  size: "default",
  disabled: false,
  validateOnRuleChange: true,
  loading: false,
  confirmText: "确定",
  cancelText: "取消",
  autoResetForm: true,
});

const emit = defineEmits<{
  "update:modelValue": [value: boolean];
  confirm: [formData: Record<string, any>];
  cancel: [];
  open: [];
  opened: [];
  close: [];
  closed: [];
  "open-auto-focus": [];
  "close-auto-focus": [];
}>();

// 响应式数据
const formRef = ref();

// 计算属性
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit("update:modelValue", value),
});

// 方法
const handleOpen = () => {
  emit("open");
};

const handleOpened = () => {
  emit("opened");
};

const handleClose = () => {
  emit("close");

  // 自动重置表单
  if (props.autoResetForm) {
    nextTick(() => {
      formRef.value?.resetFields();
    });
  }
};

const handleClosed = () => {
  emit("closed");
};

const handleOpenAutoFocus = () => {
  emit("open-auto-focus");
};

const handleCloseAutoFocus = () => {
  emit("close-auto-focus");
};

const handleConfirm = async () => {
  if (!formRef.value) return;

  try {
    await formRef.value.validate();
    emit("confirm", props.formData);
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};

const handleCancel = () => {
  emit("cancel");
  visible.value = false;
};

// 暴露方法
defineExpose({
  formRef,
  validate: () => formRef.value?.validate(),
  resetFields: () => formRef.value?.resetFields(),
  clearValidate: () => formRef.value?.clearValidate(),
  validateField: (field: string) => formRef.value?.validateField(field),
});
</script>

<style scoped>
.form-dialog-content {
  max-height: 60vh;
  overflow-y: auto;
  padding: 0 10px;
}

.form-dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

:deep(.el-dialog) {
  .el-dialog__body {
    padding: 20px 24px;
  }

  .el-dialog__footer {
    padding: 16px 24px 24px;
    border-top: 1px solid #ebeef5;
  }
}

:deep(.el-form) {
  .el-form-item {
    margin-bottom: 20px;

    &:last-child {
      margin-bottom: 0;
    }
  }

  .el-form-item__label {
    font-weight: 500;
    color: #303133;
  }

  .el-form-item__content {
    .el-input,
    .el-select,
    .el-date-editor,
    .el-cascader,
    .el-radio-group,
    .el-checkbox-group {
      width: 100%;
    }
  }
}
</style>
